package cn.jetpiece.cloud.joss.app.modular.storage.factory;

import cn.jetpiece.cloud.joss.app.modular.object.entity.Provider;
import cn.jetpiece.cloud.joss.app.modular.object.entity.Region;
import cn.jetpiece.cloud.joss.app.modular.object.enums.BasicExceptionEnum;
import cn.jetpiece.cloud.joss.app.modular.object.model.BucketInfo;
import cn.jetpiece.cloud.joss.app.modular.storage.service.JossClient;
import cn.jetpiece.cloud.joss.app.modular.storage.service.impl.MinioJossClient;
import cn.jetpiece.cloud.joss.app.modular.storage.service.impl.ObsJossClient;
import cn.jetpiece.cloud.joss.app.modular.storage.service.impl.OssJossClient;
import cn.jetpiece.cloud.model.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 服务商对象存储连接客户端工厂
 *
 * @author XuJZ
 */
@Slf4j
public class JossClientFactory {

    public static final Map<String, JossClient> CLIENTS = new ConcurrentHashMap<>();
    public static final Map<Integer, Class<? extends JossClient>> CLIENT_TYPES = new ConcurrentHashMap<>();

    static {
        CLIENT_TYPES.put(1, OssJossClient.class);
        CLIENT_TYPES.put(2, ObsJossClient.class);
        CLIENT_TYPES.put(4, MinioJossClient.class);
    }

    /**
     * 获取服务商连接客户端
     *
     * @param bucketInfo 桶信息
     * @return 连接客户端
     */
    public static JossClient getJossClient(BucketInfo bucketInfo) {
        String key = bucketInfo.getRegion().getProtocol() + bucketInfo.getRegion().getInternetEndpoint() + "|" + bucketInfo.getProvider().getAccessKey() + "|" + bucketInfo.getProvider().getSecretKey();
        if (CLIENTS.containsKey(key)) {
            return CLIENTS.get(key);
        }
        return getJossClient(bucketInfo.getProvider().getProviderType(), bucketInfo.getRegion().getProtocol(), bucketInfo.getRegion().getInternetEndpoint(), bucketInfo.getProvider().getAccessKey(), bucketInfo.getProvider().getSecretKey());
    }

    /**
     * 获取服务商连接客户端
     *
     * @param provider 服务商信息
     * @param region   域信息
     * @return 连接客户端
     */
    public static JossClient getJossClient(Provider provider, Region region) {
        String key = region.getProtocol() + region.getInternetEndpoint() + "|" + provider.getAccessKey() + "|" + provider.getSecretKey();
        if (CLIENTS.containsKey(key)) {
            return CLIENTS.get(key);
        }
        return getJossClient(provider.getProviderType(), region.getProtocol(), region.getInternetEndpoint(), provider.getAccessKey(), provider.getSecretKey());
    }

    /**
     * 获取服务商连接客户端
     *
     * @param providerType 服务商类型
     * @param protocol     协议
     * @param endpoint     服务商地址
     * @param accessKey    公钥
     * @param secretKey    密钥
     * @return 连接客户端
     */
    public static JossClient getJossClient(Integer providerType, String protocol, String endpoint, String accessKey, String secretKey) {
        String key = protocol + endpoint + "|" + accessKey + "|" + secretKey;
        if (CLIENTS.containsKey(key)) {
            return CLIENTS.get(key);
        }
        Class<?> aClass = CLIENT_TYPES.get(providerType);
        if (aClass == null) {
            throw new ServiceException(BasicExceptionEnum.PROVIDER_CLIENT_CREATE_ERROR);
        }
        try {
            Constructor<?> constructor = aClass.getDeclaredConstructor(String.class,String.class,String.class);
            Object o = constructor.newInstance(protocol + endpoint,accessKey,secretKey);
            JossClient jossClient = (JossClient) o;
            CLIENTS.put(key, jossClient);
            return jossClient;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(BasicExceptionEnum.PROVIDER_CLIENT_CREATE_ERROR);
        }
    }
}
